#include "stdafx.h"
#include "CppUnitTest.h"

#include <HSModel/Model3DStorage.h>
#include <HSModel/World.h>
#include <HSModel/GameController.h>
#include <HSModel/WorldUpdater.h>
#include <HSModel/SharedConstants.h>
#include <HSModel/Model3D.h>
#include <HSModel/ObjParser.h>
#include <HSModel/Tree.h>
#include <HSModel/Bench.h>
#include <HSModel/BalloonsShop.h>
#include <HSModel/Ground.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace HSModelTests
  {
  TEST_CLASS(WorldUpdaterTests)
    {
    public:

      TEST_METHOD(ShouldAddTreeInTheMiddleOfCell)
        {
        World world;
        GameController game_controller;
        WorldUpdater world_updater(world, game_controller);

        const TVector3 position = TVector3(17, 59, 144);
        world_updater.AddTree(position);

        const int row = static_cast<int>(position.X() / GroundConstants::CELL_SIZE);
        const int column = static_cast<int>(position.Y() / GroundConstants::CELL_SIZE);
        const double exp_x = (row + 0.5) * GroundConstants::CELL_SIZE;
        const double exp_y = (column + 0.5) * GroundConstants::CELL_SIZE;

        auto trees = world.GetItems<Tree>();
        Assert::AreEqual(1u, trees.size());
        Assert::AreEqual(exp_x, trees[0]->GetPosition().X(), 1e-9);
        Assert::AreEqual(exp_y, trees[0]->GetPosition().Y(), 1e-9);
        }

      TEST_METHOD(ShouldAddBenchInTheMiddleOfCell)
        {
        World world;
        GameController game_controller;
        WorldUpdater world_updater(world, game_controller);

        const TVector2 position = TVector2(17, 59);
        world.GetGround()->CreateWalkway(position + TVector2(GroundConstants::CELL_SIZE, 0));
        world_updater.AddBench(position);

        const int row = static_cast<int>(position.X() / GroundConstants::CELL_SIZE);
        const int column = static_cast<int>(position.Y() / GroundConstants::CELL_SIZE);
        const double exp_x = (row + 0.5) * GroundConstants::CELL_SIZE;
        const double exp_y = (column + 0.5) * GroundConstants::CELL_SIZE;

        auto benches = world.GetItems<Bench>();
        Assert::AreEqual(1u, benches.size());
        Assert::AreEqual(exp_x, benches[0]->GetPosition().X(), 1e-9);
        Assert::AreEqual(exp_y, benches[0]->GetPosition().Y(), 1e-9);
        }

      TEST_METHOD(ShouldAddBalloonShopInTheMiddleOfCell)
        {
        World world;
        GameController game_controller;
        WorldUpdater world_updater(world, game_controller);
        world_updater.CreateWalkway(TVector2(0, 59));

        const TVector3 position = TVector3(17, 59, 144);
        world_updater.AddBalloonsShop(position);

        const int row = static_cast<int>(position.X() / GroundConstants::CELL_SIZE);
        const int column = static_cast<int>(position.Y() / GroundConstants::CELL_SIZE);
        const double exp_x = (row + 0.5) * GroundConstants::CELL_SIZE;
        const double exp_y = (column + 0.5) * GroundConstants::CELL_SIZE;

        auto shops = world.GetItems<BalloonsShop>();
        Assert::AreEqual(1u, shops.size());
        Assert::AreEqual(exp_x, shops[0]->GetPosition().X(), 1e-9);
        Assert::AreEqual(exp_y, shops[0]->GetPosition().Y(), 1e-9);
        }
    };
  }